/**
IP地址是由4个 0-255 之间的整数构成的，用 "." 符号相连。
二进制的IP地址格式有32位，例如：10000011，01101011，00000011，00011000;每八位用十进制表示就是 131.107.3.24
子网掩码是用来判断任意两台计算机的IP地址是否属于同一子网络的根据。
子网掩码与IP地址结构相同，是32位二进制数，由 1 和 0 组成，且 1 和 0 分别连续，其中网络号部分全为 “1” 和主机号部分全为 “0”。
你可以简单的认为子网掩码是一串连续的1和一串连续的0拼接而成的32位二进制数，左边部分都是1，右边部分都是0。
利用子网掩码可以判断两台主机是否在同一子网中。
若两台主机的IP地址分别与它们的子网掩码进行逻辑“与”运算（按位与/AND）后的结果相同，则说明这两台主机在同一子网中。

示例：
I P 地址　 192.168.0.1
子网掩码　 255.255.255.0

转化为二进制进行运算：

I P 地址　  11000000.10101000.00000000.00000001
子网掩码　11111111.11111111.11111111.00000000

AND运算   11000000.10101000.00000000.00000000

转化为十进制后为：
192.168.0.0


I P 地址　 192.168.0.254
子网掩码　 255.255.255.0


转化为二进制进行运算：

I P 地址　11000000.10101000.00000000.11111110
子网掩码  11111111.11111111.11111111.00000000

AND运算  11000000.10101000.00000000.00000000

转化为十进制后为：
192.168.0.0

通过以上对两台计算机IP地址与子网掩码的AND运算后，我们可以看到它运算结果是一样的。均为192.168.0.0，所以这二台计算机可视为是同一子网络。

输入一个子网掩码以及两个ip地址，判断这两个ip地址是否是一个子网络。
若IP地址或子网掩码格式非法则输出1，若IP1与IP2属于同一子网络输出0，若IP1与IP2不属于同一子网络输出2。

注:
有效掩码与IP的性质为：
1. 掩码与IP每一段在 0 - 255 之间
2. 掩码的二进制字符串前缀为网络号，都由‘1’组成；后缀为主机号，都由'0'组成

输入描述：
3行输入，第1行是输入子网掩码、第2，3行是输入两个ip地址
题目的示例中给出了三组数据，但是在实际提交时，你的程序可以只处理一组数据（3行）。

输出描述：
若IP地址或子网掩码格式非法则输出1，若IP1与IP2属于同一子网络输出0，若IP1与IP2不属于同一子网络输出2

*/
// const readline = require('readline')
// const rl = readline.createInterface({
//   input:process.stdin,
//   output:process.stdout
// })

// 校验 ip 是否有效
function valideIp(ip, mask = false) {
  if (!ip) return false
  let ipArr = ip.split('.')
  if (ipArr.length !== 4) return false
  if (mask) { return ipArr.filter(item => {
    return Number(item) === 0 || Number(item) === 255 || !item.includes('01')
  }).length === 4 }
  return ipArr.some(ipstr => Number(ipstr) < 0 || Number(ipstr) > 255)
}

function transform(inArr) {
  // 子网掩码 只要包含 01 就不合法
  if (!(valideIp(inArr[0], true))) return 1
  for(let i = 0; i < inArr.length; i++) {
    if (valideIp(inArr[i])) return 1
    // ip1 ip2 子网掩码 做与操作
    
    inArr[i] = inArr[i].split('.').map((item) => {
      return Number(item).toString(2).padStart(8, 0)
    })
  }
  // 第一 第二，第一，第三 做 and 运算
  let ip1 = inArr[0]
  let ip2 = inArr[1]
  let ip3 = inArr[2]
  let res1 = []
  let res2 = []
  ip1.map((item, idx) => {
    res1.push(item.split('').map((inItem, inIdx) => { return inItem & ip2[idx][inIdx] }))
    res2.push(item.split('').map((inItem, inIdx) => {  return inItem & ip3[idx][inIdx] }))
  })
  // 二进制转 十进制
  res1 = res1.map((resItem) => { return parseInt(resItem.join(''), 2) }).join('.')
  res2 = res2.map((resItem) => { return parseInt(resItem.join(''), 2) }).join('.')
  if (res1 === res2) return 0
  return 2
}

// 本地测试
let ipArrs = ['254.255.0.0', '85.122.52.249', '10.57.28.117']
console.log(transform(ipArrs))

// let lineArr = []
// // 提交测试
// rl.on('line', (line) => {
//   lineArr.push(line)
//   if (lineArr.length === 3) {
//     console.log(transform(lineArr))
//   }
// })